class Array
  def method_missing(meth)
      half = (self.size - 1)/2
      return self[0..half]  if(meth.to_s == 'left_half')
      return self[half + 1..self.size-1] if(meth.to_s == 'right_half')
      
      if meth.to_s == 'count_inversions_and_sort!'
        return 0 if (0..1).include? self.size
        count1 = self.left_half.count_inversions_and_sort!
        count2 = self.right_half.count_inversions_and_sort!
        count3 = self.count_inversions_and_merge!
        return count1 + count2 + count3

      elsif meth.to_s == 'count_inversions_and_merge!'
        i, j, count = 0, 0, 0
        result = []
        a, b = self.left_half, self.right_half
        while i < a.size and j < b.size
          if a[i] > b[j] #here we actually count split inversions
            result.push(b[j])
            j += 1
            count += (a.size - i) #count how many in left half > b[j]
          else
            result.push(a[i])
            i += 1
          end
        end
        while i < a.size; result.push(a[i]); i+=1; end
        while j < b.size; result.push(b[j]); j+=1;  end
        self.replace result
        return count
        
      elsif meth.to_s == 'makezero!'
      self[0..self.size-1] = [0, 0, 0, 0]
      else
        super
      end
  end 
end

def merge_sort (ary)
  return ary if (0..1).include? ary.size
  a = merge_sort ary.left_half
  b = merge_sort ary.right_half
  merge_arrays  a, b
end

def merge_arrays (a, b)
  i, j = 0, 0
  result = []
  while i < a.size and j < b.size
    if a[i] < b[j]
      result.push(a[i])
      i+=1
    else
      result.push(b[j])
      j+=1
    end
  end
  while i < a.size; result.push(a[i]); i+=1; end
  while j < b.size; result.push(b[j]); j+=1;  end
  result
end





def my_func
  a = [1, 2 ,3]
end

p "MY TEST"
ar = [1,2,3]
b = ar[0..1]
b.replace([3,4])
p ar

a = [10, 30, -1, 14, 12]
b = [5, 4, 1, 2]
p merge_sort(a)
#p a.right_half

c = [2, 1, 0]
c.count_inversions_and_sort!
p "printing c"
p c
#p c.left_half

p a.count_inversions_and_sort!
p "new a= #{a}"
p a



  
